Report with ZK: Using JasperReports As an Example
Henri Chen, Principal Engineer, Potix Corporation
November 19, 2007
Introduction
Report is no doubt a required feature in most enterprise applications. In this article, I want to demonstrate the standard practice to handle reports and how to do it with a famous Java opensource report engine, JasperReports, as an example.
The Operation Flow
The operation flow is quite straightforward. you first have the report engine to generate the final report "stream", be it PDF, RTF, or other formats, the stream is then responsed back to an iframe component. The reader/plugin installed on the browser side will then pick up the job and show the report automatically. If there is no proper reader/plugin installed, a browser download window will popup waiting user's decision to download the report stream as a file for you. The following is the figure that shows the flow.
Report in Action
As you might have known, ZK is a server-centric Ajax framework. That means, your application is running on the server side while ZK framework handles the rest for you. Your application can access to the full power of the server and the full resources in the server easily. Your application runs with the report engine in the server side along with the data sources required to generate the report. There is no remote-procedure-call(RPC) hassles and you can call directly any Java libraries in the server side without worrying about security issues.
The Example Code
The following is the example code with the JasperReports engine. I shamlessly "steal" an existing example directly from the JasperReports project and add some little ZK glue codes.
<?page style="height:100%" ?>
<window width="100%" height="100%">
<borderlayout height="100%">
<north maxsize="24" size="24" border="0">
<button label="Report!" onClick="doReport()"/>
</north>
<center border="none" flex="true">
<iframe id="report" />
</center>
</borderlayout>
<zscript><![CDATA[
import java.io.*;
import java.sql.*;
import org.zkoss.util.media.AMedia;
import net.sf.jasperreports.engine.JasperRunManager;
void doReport() {
InputStream is = null;
try {
//generate report pdf stream
is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("FirstJasper.jasper");
final Map params = new HashMap();
params.put("ReportTitle", "The First Jasper Report Ever");
params.put("MaxOrderID", new Integer(10500));
final byte[] buf =
JasperRunManager.runReportToPdf(is, params, getConnection());
//prepare the AMedia for iframe
final InputStream mediais = new ByteArrayInputStream(buf);
final AMedia amedia =
new AMedia("FirstReport.pdf", "pdf", "application/pdf", mediais);
//set iframe content
report.setContent(amedia);
} catch (Exception ex) {
throw new RuntimeException(ex);
} finally {
if (is != null) {
is.close();
}
}
}
private static Connection getConnection()
throws ClassNotFoundException, SQLException
{
//Change these settings according to your local configuration
String driver = "org.hsqldb.jdbcDriver";
String connectString = "jdbc:hsqldb:hsql://localhost";
String user = "sa";
String password = "";
Class.forName(driver);
Connection conn = DriverManager.getConnection(connectString, user, password);
return conn;
}
]]></zscript>
</window>
The concept is simple. The end user request a report by clicking the button and the "onClick" event handler in the application request the JasperReports engine to generate the PDF report stream. The application then pack the stream into a ZK media with proper file extension and mime-type and set it as the content of the iframe component. The application ends here and the rest is done automatically by the ZK framework. It generates an url token and set the url into iframe's src attribute. This causes the iframe in browser side to request a new page from the given new url. The ZK framework then identifies the request and response with the previously prepared PDF stream back. Until this moment, the PDF-reader/plugin installed on the end user's browser side picks up the job and show the stream in the iframe as a PDF document.
Summary
The practice of having the server to render the result and then send it back to iframe is not limited to the PDF stream only. Theoretically, you can have an Excel engine to generate Excel streams, an RTF engine to generate RTF streams, or an AutoCad engine to generate DWG streams. The imagination is the only limit. In fact, the rendering engine can be even not there in your server. You can just request those rendering results from a web service and so on. I think this is the power of a server centric framework like ZK. Because you run your applications in the server, you got the full power of the server and you enjoy all convenience brought by the server-centric architecture.
I wish this example explains the common question asked on forum regarding how to generate report in ZK. Should you have other questions regarding this practice or you think there is a better approach, please do not hesitate in leaving a comment. We love to hear from you.
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |